package com.youle.common.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;

import com.alibaba.fastjson.JSONObject;
import com.cloopen.rest.sdk.CCPRestSDK;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;

/**
 * 
  * @ClassName: SmsUtil
  * @Description: 短信工具类
 */
public class SmsUtil {
	private final static Log log = LogFactory.getLog(SmsUtil.class);
	
	/**
	 * FunName:sendCode Description:发送验证码到手机
	 * 
	 * @param: 调用短信接口的url
	 * @return boolean
	 * @throws UnsupportedEncodingException 
	 * @Create Date: 2014-7-22
	 * @Author:fengchao
	 */
	public static boolean sendCode(String phone,String code, Integer areaNo){
		// 如果为1，则采用优先通道，中舜短信通道
		String send_code = code;
		try {
			send_code = URLEncoder.encode(code + ConfigProperty.getProperty("verify_code"), "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		StringBuffer url = new StringBuffer();
		
		url.append(ConfigProperty.getProperty("hk_code_url"))
		.append("?user=").append(ConfigProperty.getProperty("hk_code_name"))
		.append("&pwd=").append(ConfigProperty.getProperty("hk_code_pw"))
		.append("&msg=").append(send_code)
		.append("&phone=").append(areaNo + phone)
		.append("&accountno=").append(ConfigProperty.getProperty("hk_account_no"));

		boolean flag = false;
		URL u;
		try {
			u = new URL(url.toString());
			BufferedReader buffered = new BufferedReader(new InputStreamReader(u.openStream()));
			String message = "" ;
			String line = "" ;
			switch (areaNo) {
				case 852:
					int index = 0;
					while((line = buffered.readLine())!=null){
								if(index++ > 0){
									message += line;
								}
					}
					break;
				default:
					message = buffered.readLine();
				break;
			}
			
			//如果有“<”，代表采用的是中舜的短信接口，返回的是xml字符串格式,需xml解析
			if(message.contains("<")){
			try {
				StringReader xmlReader = new StringReader(message);  
				InputSource xmlSource = new InputSource(xmlReader);
				SAXBuilder builder = new SAXBuilder();  
			    Document doc = builder.build(xmlSource);  
			    Element elt = doc.getRootElement();
			    switch (areaNo) {
					case 852:
						elt = elt.getChild("msg").getChild("msg_status");
						line = elt.getText();
					break;
					default:
						 line = elt.getText();
					break;
			    }
			   
			} catch (Exception e) {
				log.error("返回短信发送状态时解析xml错误",e);
			}
		 }else{
			 line = message.substring(0,2);
		 }
			 //如果发送成功，短信网关会返回0
			if ("03".equals(line)) {
				flag = true;
			}else if("0".equals(line)){
				flag = true;
			}else if(line.equals("100")){
				flag = true;
			}else{
				log.error(message);
			}
		} catch (IOException e) {
			 log.error("发送验证码异常",e);
		}
		return flag;
	}
	
	/**
	 * <p>发送短信</p>  
	 * <p>自动判断号码所在区域，调用不同的服务商发送消息</p>  
	 * @param phone
	 * @param code
	 * @param type
	 * @param areaNo
	 * @return   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年7月12日 下午1:56:04    <br>
	 */
	public static boolean sendCode(String phone, String code, Integer type, Integer areaNo){
		boolean flag = false;
		switch (areaNo) {
			case 86:
				JSONObject smsParam = new JSONObject();
				smsParam.put("code", code);
				if(type == null){
					type = 1;
				}
				String smsTemplateCode = ConfigProperty.getProperty("sms.aliyun.template"+type);
				String smsSign = ConfigProperty.getProperty("sms.aliyun.sign"+type);
				flag = sendByAlidayu(phone, smsTemplateCode, smsParam.toJSONString(), smsSign);
				break;
			case 852:
				flag = sendCode(phone, code, areaNo);
				break;
		}
		return flag;
		
	}

	/**
	  * @Description: 阿里大鱼发送短信
	  * @param phone  电话  				示例：15871383472
	  * @param smsTemplateCode			示例：SMS_3685120
	  * @param smsParam					示例：{\"code\":\"1234\"}
	  * @param smsSign					示例：身份验证
	  * @return  true/false(成功/失败)
	 */
	public static boolean sendByAlidayu(String phone, String smsTemplateCode, String smsParam, String smsSign){
		boolean result = true;
		try {
			String appkey = getText("sms.aliyun.appkey");
			String secret = getText("sms.aliyun.secret");
			String addr = getText("sms.aliyun.addr");
			TaobaoClient client = new DefaultTaobaoClient(addr, appkey, secret);
			AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
			req.setSmsType("normal");
			req.setSmsFreeSignName(smsSign);
			//参数
			req.setSmsParamString(smsParam);
			req.setRecNum(phone);
			req.setSmsTemplateCode(smsTemplateCode);
			AlibabaAliqinFcSmsNumSendResponse rsp = client.execute(req, secret);
			
			if(rsp != null && StringUtils.isNotBlank(rsp.getBody())){
				//返回错误信息
				if(rsp.getBody().indexOf("error_response") != -1){
					log.error(rsp.getBody());
					result = false;
				}
			}else{
				result = true;
			}
			
			return result;
		} catch (Exception e) {
			 log.error("阿里大鱼发送短信异常",e);
			 throw new RuntimeException("阿里大鱼发送短信异常");
		}
	}
	
	/**
	 * 发送语音验证码
	 */
	public static boolean sendVoiceCode(String code, String phone){
		log.info("发送语音验证码" + code);
		HashMap<String, Object> result = null;
		CCPRestSDK restAPI = new CCPRestSDK();
		restAPI.init("app.cloopen.com", "8883");// 初始化服务器地址和端口，格式如下，服务器地址不需要写https://
		restAPI.setAccount(getText("accountSid"), getText("accountToken"));// 初始化主帐号名称和主帐号令牌
		restAPI.setAppId(getText("AppId"));// 初始化应用ID
		result = restAPI.voiceVerify(code, phone,getText("view_phone"),getText("play_count"),"");

		if("000000".equals(result.get("statusCode"))){
			//正常返回输出data包体信息（map）
			@SuppressWarnings("unchecked")
			HashMap<String, Object> hashMap = (HashMap<String, Object>) result.get("data");
			HashMap<String,Object> data = hashMap;
			Set<String> keySet = data.keySet();
			for(String key:keySet){
				Object object = data.get(key);
				log.info(key +" = "+object);
			}
			return true;
		}else{
			//异常返回输出错误码和错误信息
			log.error("错误码=" + result.get("statusCode") +" 错误信息= "+result.get("statusMsg"));
			return false;
		}
		
	}
	/**
	 * 
	  * @Description: 获取资源配置
	  * @param key
	  * @return
	  * @author 马正正
	  * @date 2015年11月9日
	 */
	private static String getText(String key){
		return ConfigProperty.getProperty(key);
	}
	
}
